package com.example.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gitee.loyo.NotificationService;
import com.gitee.loyo.Request;
import com.gitee.loyo.Result;
import com.gitee.loyo.config.ChargeConst;
import com.gitee.loyo.config.ChargeNotifyProperties;
import com.gitee.loyo.config.ChargeProperties;
import com.gitee.loyo.data.ConnectorStatusInfo;
import com.gitee.loyo.data.Token;
import com.gitee.loyo.enums.ConnectorStatus;
import com.gitee.loyo.enums.LockStatus;
import com.gitee.loyo.enums.ParkStatus;
import com.gitee.loyo.enums.StartChargeSeqStat;
import com.gitee.loyo.post.*;
import com.gitee.loyo.result.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/evcs/v1")
public class ChargingController implements NotificationService {
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Resource
    ChargeNotifyProperties chargeNotifyProperties;
    @Resource
    ObjectMapper objectMapper;

    @Override
    @PostMapping("/query_token")
    public Result<Token> queryToken(@RequestBody Request<QueryTokenPost> post) {
        QueryTokenPost data = post.getData();
        if(data == null || data.getOperatorId() == null
            || data.getOperatorSecret() == null){
            Result<Token> result = new Result<>(post);
            result.setRet(4004);
            result.setMsg("请求业务的参数不合法，各接口定义自己的必须参数");
            return result;
        }
        if(!chargeNotifyProperties.getOperatorId().equals(data.getOperatorId())){
            Result<Token> result = new Result<>(post);
            result.setRet(0);
            Token token = new Token();
            token.setOperatorId(chargeNotifyProperties.getOperatorId());
            token.setSuccStat(1);
            token.setFailReason(1);
            result.setData(token);
            return result;
        }
        if(!chargeNotifyProperties.getOperatorSecret().equals(data.getOperatorSecret())){
            Result<Token> result = new Result<>(post);
            result.setRet(0);
            Token token = new Token();
            token.setOperatorId(chargeNotifyProperties.getOperatorId());
            token.setSuccStat(1);
            token.setFailReason(2);
            result.setData(token);
            return result;
        }

        // 生成令牌
        Result<Token> result = new Result<>(post);
        result.setRet(0);
        Token token = new Token();
        token.setOperatorId(chargeNotifyProperties.getOperatorId());
        token.setAccessToken(UUID.randomUUID().toString());
        token.setTokenAvailableTime(24 * 3600);
        result.setData(token);
        // 保存到Redis
        redisTemplate.opsForValue().set(
            ChargeConst.REDIS_TCEC_OPS_TOKEN + chargeNotifyProperties.getOperatorId(),
            token,
            24 * 3600
        );
        log.info("OperatorID {} query token: {}", token.getOperatorId(), token.getAccessToken());
        return result;
    }

    @Override
    @PostMapping("/notification_stationStatus")
    public Result<NotifyStationStatusResult> notifyStationStatus(@RequestBody Request<NotifyStationStatusPost> post) {
        try {
            log.info("notification_stationStatus: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try{
            ConnectorStatusInfo connectorStatusInfo = post.getData().getConnectorStatusInfo();
            log.info("设备状态变化推送 {}: {}, 地锁{}, 车位{}",
                connectorStatusInfo.getConnectorId(),
                ConnectorStatus.valueOf(connectorStatusInfo.getStatus()).getText(),
                LockStatus.valueOf(connectorStatusInfo.getLockStatus()).getText(),
                ParkStatus.valueOf(connectorStatusInfo.getParkStatus()).getText()
            );
        }catch (Exception e){

        }
        Result result = new Result(post);
        result.setRet(0);
        NotifyStationStatusResult data = new NotifyStationStatusResult();
        data.setStatus(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @Override
    @PostMapping("/notification_start_charge_result")
    public Result<NotifyStartChargeResultResult> notifyStartChargeResult(@RequestBody Request<NotifyStartChargeResultPost> post) {
        try {
            log.info("notification_start_charge_result: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try{
            NotifyStartChargeResultPost startChargeResultPost = post.getData();
            log.info("推送启动充电结果 {}: {}",
                startChargeResultPost.getConnectorId(),
                StartChargeSeqStat.valueOf(startChargeResultPost.getStartChargeSeqStat()).getText()
            );
        }catch (Exception e){

        }
        Result result = new Result(post);
        result.setRet(0);
        NotifyStartChargeResultResult data = new NotifyStartChargeResultResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setSuccStat(0);
        data.setFailReason(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @Override
    @PostMapping("/notification_equip_charge_status")
    public Result<NotifyEquipChargeStatusResult> notifyEquipChargeStatus(@RequestBody Request<NotifyEquipChargeStatusPost> post) {
        try {
            log.info("notification_equip_charge_status: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try{
            NotifyEquipChargeStatusPost equipChargeStatusPost = post.getData();
            log.info("推送充电状态 {}: {}, 电费{}, 服务费{}, 总金额{}",
                equipChargeStatusPost.getConnectorId(),
                StartChargeSeqStat.valueOf(equipChargeStatusPost.getStartChargeSeqStat()).getText(),
                equipChargeStatusPost.getElecMoney(),
                equipChargeStatusPost.getServiceMoney(),
                equipChargeStatusPost.getTotalMoney()
            );
        }catch (Exception e){

        }
        Result result = new Result(post);
        result.setRet(0);
        NotifyStartChargeResultResult data = new NotifyStartChargeResultResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setSuccStat(0);
        data.setFailReason(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @Override
    @PostMapping("/notification_stop_charge_result")
    public Result<NotifyStopChargeResultResult> notifyStopChargeResult(@RequestBody Request<NotifyStopChargeResultPost> post) {
        try {
            log.info("notification_stop_charge_result: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try{
            NotifyStopChargeResultPost equipChargeStatusPost = post.getData();
            log.info("推送停止充电结果 {}: {}",
                equipChargeStatusPost.getConnectorId(),
                StartChargeSeqStat.valueOf(equipChargeStatusPost.getStartChargeSeqStat()).getText()
            );
        }catch (Exception e){

        }
        Result result = new Result(post);
        result.setRet(0);
        NotifyStopChargeResultResult data = new NotifyStopChargeResultResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setSuccStat(0);
        data.setFailReason(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @Override
    @PostMapping("/notification_charge_order_info")
    public Result<NotifyChargeOrderInfoResult> notifyChargeOrderInfo(@RequestBody Request<NotifyChargeOrderInfoPost> post) {
        try {
            log.info("notification_charge_order_info: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try{
            NotifyChargeOrderInfoPost chargeOrderInfoPost = post.getData();
            log.info("推送充电订单 {}: 电费{}, 服务费{}, 总金额{}",
                chargeOrderInfoPost.getConnectorId(),
                chargeOrderInfoPost.getTotalElecMoney(),
                chargeOrderInfoPost.getTotalServiceMoney(),
                chargeOrderInfoPost.getTotalMoney()
            );
        }catch (Exception e){

        }
        Result result = new Result(post);
        result.setRet(0);
        NotifyChargeOrderInfoResult data = new NotifyChargeOrderInfoResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setConnectorId(post.getData().getConnectorId());
        data.setConfirmResult(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @Override
    @PostMapping("/check_charge_order")
    public Result<CheckChargeOrderResult> checkChargeOrder(@RequestBody Request<CheckChargeOrderPost> post) {
        try {
            log.info("check_charge_order: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try{
            CheckChargeOrderPost checkChargeOrderPost = post.getData();
            log.info("推送订单对账结果信息 {} - {} : 总金额{}, 总电量{}",
                checkChargeOrderPost.getStartTime(),
                checkChargeOrderPost.getEndTime(),
                checkChargeOrderPost.getTotalOrderMoney(),
                checkChargeOrderPost.getTotalOrderPower()
            );
            if(checkChargeOrderPost.getChargeOrders() != null){
                for (CheckChargeOrderPost.ChargeOrder chargeOrder : checkChargeOrderPost.getChargeOrders()) {
                    log.info("明细 {}: 总金额{}, 总电量{} ", chargeOrder.getStartChargeSeq(), chargeOrder.getTotalPower(), chargeOrder.getTotalMoney());
                }
            }
        }catch (Exception e){

        }
        Result result = new Result(post);
        result.setRet(0);
        CheckChargeOrderResult data = new CheckChargeOrderResult();
        data.setCheckOrderSeq(post.getData().getCheckOrderSeq());
        data.setStartTime(post.getData().getStartTime());
        data.setEndTime(post.getData().getEndTime());
        data.setTotalDisputeOrder(0);
        data.setTotalDisputeMoney(0d);
        data.setTotalDisputePower(0d);
        data.setDisputeOrders(Collections.emptyList());
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }
}
